package it.niedermann.android.markdown.markwon.format

import android.graphics.Typeface
import android.text.SpannableString
import android.text.style.StyleSpan
import android.util.SparseIntArray
import android.view.ActionMode
import android.view.Menu
import android.view.MenuItem
import com.gitee.wsl.android.ext.device.ClipboardExt.getClipboardURLorNull
import io.noties.markwon.base.R
import it.niedermann.android.markdown.MarkdownUtil
import it.niedermann.android.markdown.markwon.MarkwonMarkdownEditor
import timber.log.Timber

class ContextBasedRangeFormattingCallback(private val editText: MarkwonMarkdownEditor) :
    ActionMode.Callback {
    override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
        mode.menuInflater.inflate(R.menu.context_based_range_formatting, menu)
        val styleFormatMap = SparseIntArray()
        styleFormatMap.append(R.id.bold, Typeface.BOLD)
        styleFormatMap.append(R.id.italic, Typeface.ITALIC)
        var item: MenuItem
        var title: CharSequence?
        var spannableString: SpannableString
        for (i in 0 until styleFormatMap.size()) {
            item = menu.findItem(styleFormatMap.keyAt(i))
            title = item.title
            spannableString = SpannableString(title)
            spannableString.setSpan(StyleSpan(styleFormatMap.valueAt(i)), 0, title!!.length, 0)
            item.title = spannableString
        }
        return true
    }

    override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
        val text = editText.text
        if (text != null) {
            val selectionStart = editText.selectionStart
            val selectionEnd = editText.selectionEnd
            if (selectionStart >= 0 && selectionStart <= text.length) {
                if (MarkdownUtil.selectionIsInLink(text, selectionStart, selectionEnd)) {
                    menu.findItem(R.id.link).isVisible = false
                    Timber.tag(TAG)
                        .i("Hide link menu item because the selection is already within a link.")
                }
            } else {
                Timber.tag(TAG)
                    .e("SelectionStart is $selectionStart . Expected to be between 0 and ${text.length}")
            }
        }
        return false
    }

    override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
        val editable = editText.text
        if (editable != null) {
            val itemId = item.itemId
            val start = editText.selectionStart
            val end = editText.selectionEnd
            if (itemId == R.id.bold) {
                val newSelection = MarkdownUtil.togglePunctuation(editable, start, end, "**")
                editText.setMarkdownStringModel(editable)
                editText.setSelection(newSelection)
                return true
            } else if (itemId == R.id.italic) {
                val newSelection = MarkdownUtil.togglePunctuation(editable, start, end, "*")
                editText.setMarkdownStringModel(editable)
                editText.setSelection(newSelection)
                return true
            } else if (itemId == R.id.link) {
                val newSelection =
                    MarkdownUtil.insertLink(editable, start, end, getClipboardURLorNull())
                editText.setMarkdownStringModel(editable)
                editText.setSelection(newSelection)
                return true
            }
        } else {
            Timber.tag(TAG).e("Editable is null")
        }
        return false
    }

    override fun onDestroyActionMode(mode: ActionMode) {
        // Nothing to do here...
    }

    companion object {
        private val TAG = ContextBasedRangeFormattingCallback::class.java.simpleName
    }
}